package com.lx.spring.aop.proxy;

import org.springframework.cglib.proxy.Enhancer;
import org.springframework.cglib.proxy.MethodInterceptor;
import org.springframework.cglib.proxy.MethodProxy;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;

public class ProxyDemo {

    public static void main(String[] args) {

        人 张三 = new 被告();
        人 罗翔 = new 律师();
        人 罗翔2 = new 律师2();
        //代理
        ((律师) 罗翔).person = 张三;
        罗翔.say();
        System.out.println("-------------------------");
        罗翔2.say();
        System.out.println("-------------------------");
        人 a = jdkProxy(张三);
        a.say();
        System.out.println("-------------------------");
        人 ab = jdkProxy(张三);
        ab.say();
        System.out.println("-------------------------");



    }


    //基于接口实现动态代理, 有JDK提供方法
    public static <T> T jdkProxy(T t) {
        return (T) Proxy.newProxyInstance(
                t.getClass().getClassLoader(),
                t.getClass().getInterfaces(),
                (proxy, method, args) -> {
                    if (method.getName().equals("say")) {
                        System.out.println("被告积极配合调查");
                        Object ret = method.invoke(t, args);
                        System.out.println("根据宪法第108条规定,被告应从轻处罚或无罪");
                        return ret;
                    }
                    return null;
                }
        );
    }
    //基于继承的动态代理, CGLIB(动态字节码) 提供方法
    public static  <T> T cglibProxy(T t) {
        Enhancer enhancer = new Enhancer();
        // 设置父类
        enhancer.setSuperclass(t.getClass());
        enhancer.setCallback(new MethodInterceptor() {

            @Override
            public Object intercept(Object o,
                                    Method method,
                                    Object[] objects,
                                    MethodProxy methodProxy) throws Throwable {
                // o 代理对象 , method 方法, objects 参数, methodProxy 方法代理对象
                if (method.getName().equals("say")) {
                    System.out.println("被告积极配合调查");
                    Object ret = methodProxy.invoke(t, objects);
                    System.out.println("根据宪法第108条规定,被告应从轻处罚或无罪");
                    return ret;
                }
                return null;
            }
        });
        return (T)enhancer.create();
    }
}


// 抽象主题
interface 人{
    void say();
}

// 真实主题
class 被告 implements 人{

    @Override
    public void say() {
        System.out.println("我没用罪，虽然我不知到我为什么没用罪");
    }
}


//代理主题
class 律师 implements 人{

    人 person;
    @Override
    public void say() {
        System.out.println("被告积极配合调查");
        person.say();
        System.out.println("根据宪法第108条规定,被告应从轻处罚或无罪");
    }
}

// 基于继承实现
class 律师2 extends 被告{
    @Override
    public void say() {
        System.out.println("被告积极配合调查");
        super.say();
        System.out.println("根据宪法第108条规定,被告应从轻处罚或无罪");
    }
}